package utils

import "time"

type WheelCount struct {
	cnt            int64
	slotV          []int64
	num            int
	writeIdx       int
	moveCnt        int
	ticker         *time.Ticker
	interval       time.Duration
	addTaskChannel chan int64 // 新增任务channel
	stopChannel    chan bool  // 停止channel
}

func NewWheelCount(num int, interval time.Duration) *WheelCount {
	rval := &WheelCount{
		slotV:          make([]int64, num),
		num:            num,
		interval:       interval,
		addTaskChannel: make(chan int64),
		stopChannel:    make(chan bool),
	}
	return rval
}

func (this *WheelCount) Cnt() int64 {
	return this.cnt
}

func (this *WheelCount) PushV(v int64) {
	this.addTaskChannel <- v
}

func (this *WheelCount) Start() {
	this.ticker = time.NewTicker(this.interval)
	for {
		select {
		case <-this.ticker.C:
			this.moveCnt++
			this.writeIdx = this.moveCnt % this.num
			this.cnt = this.cnt - this.slotV[this.writeIdx]
			this.slotV[this.writeIdx] = 0
		case task := <-this.addTaskChannel:
			this.slotV[this.writeIdx] += task
			this.cnt += task
		case <-this.stopChannel:
			this.ticker.Stop()
			return
		}
	}
}

func (this *WheelCount) Stop() {
	this.stopChannel <- true
}
